<?php

/**
 * Created by PhpStorm.
 * User: liuxiu
 * Date: 2022/7/14
 * Time: 18:32
 */

namespace business\elasticsearch\services;

use business\elasticsearch\models\BigDataRadarModel;

class BigDataRadarService
{
    public function subscript(
        $areaCodes,
        $bidKeywords,
        $winBidKeywords,
        $excludeKeywords,
        $isLandOpen,
        $isBuildingOpen,
        $isSaleOpen,
        $landUsageLabels,
        $saleTypes,
        $buildingTypes,
        $projectKeywords,
        $startTime,
        $endTime,
        $dataType,
        $page,
        $pageSize
    )
    {
        $condition = $this->subscriptCondition(
            $areaCodes,
            $bidKeywords,
            $winBidKeywords,
            $excludeKeywords,
            $isLandOpen,
            $isBuildingOpen,
            $isSaleOpen,
            $landUsageLabels,
            $saleTypes,
            $buildingTypes,
            $projectKeywords,
            $startTime,
            $endTime,
            $dataType
        );
        if (empty($condition)) {
            return ['total' => 0, 'list' => [], 'new_total' => 0];
        }
//        echo json_encode($condition, 256);
//        exit;
        // 统计48h内的数据的总数量
        $newDataCondition = $this->subscriptCondition(
            $areaCodes,
            $bidKeywords,
            $winBidKeywords,
            $excludeKeywords,
            $isLandOpen,
            $isBuildingOpen,
            $isSaleOpen,
            $landUsageLabels,
            $saleTypes,
            $buildingTypes,
            $projectKeywords,
            date("Y-m-d H:i:s", strtotime("-2 day")),
            $endTime,
            $dataType
        );
        $newTotal = BigDataRadarModel::find()->query($newDataCondition)->count();
        $query = BigDataRadarModel::find()->query($condition);

        $query->orderBy(['order_date' => SORT_DESC, "has_mobile" => SORT_DESC, "_id" => SORT_DESC]);

        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $searchData = $query->createCommand()->search();

        $total = 0;
        $list = [];
        if (!empty($searchData)) {
            $data = $searchData["hits"]["hits"];
            $total = $searchData["hits"]["total"];
            foreach ($data as $dv) {
                $tmp = $dv['_source'];
                if (isset($tmp["order_date"]) && strtotime($tmp["order_date"]) >= strtotime("-2 day")) {
                    $tmp["is_new"] = 1;
                } else {
                    $tmp["is_new"] = 0;
                }

                $list[] = $tmp;
            }
        }
        return ['total' => $total, 'list' => $list, 'new_total' => $newTotal];
    }


    public function subscriptCondition(
        $areaCodes,
        $bidKeywords,
        $winBidKeywords,
        $excludeKeywords,
        $isLandOpen,
        $isBuildingOpen,
        $isSaleOpen,
        $landUsageLabels,
        $saleTypes,
        $buildingTypes,
        $projectKeywords,
        $startTime,
        $endTime,
        $dataType
    )
    {
        // 时间范围匹配 and 地区匹配 and
        // ( (dataType=招标 and 招标标题匹配招标关键字 and 招标标题不包含排除词)
        // or (dataType=中标 and 招标标题匹配中标关键字 and 中标标题不包含排除词)
        // or 如果订阅了拿地 则 (dataType=土地 and (土地用途匹配成功 or 项目标题匹配项目关键词)),否则不取拿地数据
        // or 如果订阅了在建 则 (dataType=在建 and (工程用途匹配成功 or 项目标题匹配项目关键词)),否则不取在建数据
        // or 如果订阅了开盘 则 (dataType=开盘 and (在售类型匹配成功 or 项目标题匹配项目关键词)),否则不取开盘数据 )
        $query = [];
        $slop = !empty(\Yii::$app->params['CommonDataDeveloperSlop']) ? \Yii::$app->params['CommonDataDeveloperSlop'] : 2;
        $must = [];
        $query['function_score']['query']['bool']['must'] = &$must;

        if (!empty($startTime) && !empty($endTime)) {
            $must[] = ["range" => ["order_date" => ["from" => $startTime, "to" => $endTime]]];
        }

        if (!empty($areaCodes)) {
            $must[] = [
                "nested" => [
                    "path" => "locations",
                    "query" => ["bool" => [
                        "should" => [
                            ["terms" => ["locations.city_code" => $areaCodes]],
                            ["terms" => ["locations.province_code" => $areaCodes]]
                        ]
                    ]
                    ]
                ]];
        }

        $allOpptyCondition = [];
        // 招标的查询条件
        $bidCondition = [["term" => ["data_type" => "招标"]]];
        if (!empty($bidKeywords) || !empty($excludeKeywords)) {
            if (!empty($bidKeywords)) {
                $bidTitleLike = ["bool" => ["should" => []]];
                foreach ($bidKeywords as $keyword) {
                    $bidTitleLike["bool"]["should"][] = [
//                        'match' => ['title' => ["query" => $keyword]]
                        'match_phrase' => ['title' => ["query" => $keyword, 'slop' => $slop]]
                    ];
                }
                $bidCondition[] = $bidTitleLike;
            }
            if (!empty($excludeKeywords)) {
                $bidTitleNotLike = ["bool" => ["must_not" => []]];
                foreach ($excludeKeywords as $excludeKeyword) {
                    $bidTitleNotLike["bool"]["must_not"][] = [
//                        'match' => ['title' => ["query" => $excludeKeyword]]
                        'match_phrase' => ['title' => ["query" => $excludeKeyword, 'slop' => $slop]]
                    ];
                }
                $bidCondition[] = $bidTitleNotLike;
            }
        }
        // 用户未指定商机类型，或指定类型中包含招标，则查询条件里带招标带查询条件
        if (empty($dataType) || in_array("招标", $dataType)) {
            $allOpptyCondition["bool"]["should"][] = ["bool" => ["must" => $bidCondition]];
        }

        // 中标的查询条件
        $winBidCondition = [["term" => ["data_type" => "中标"]]];
        if (!empty($winBidKeywords) || !empty($excludeKeywords)) {
            if (!empty($winBidKeywords)) {
                $winBidTitleLike = ["bool" => ["should" => []]];
                foreach ($winBidKeywords as $keyword) {
                    $winBidTitleLike["bool"]["should"][] = [
//                        'match' => ['title' => ["query" => $keyword]]
                        'match_phrase' => ['title' => ["query" => $keyword, 'slop' => $slop]]
                    ];
                }
                $winBidCondition[] = $winBidTitleLike;
            }
            if (!empty($excludeKeywords)) {
                $winBidTitleNotLike = ["bool" => ["must_not" => []]];
                foreach ($excludeKeywords as $excludeKeyword) {
                    $winBidTitleNotLike["bool"]["must_not"][] = [
//                        'match' => ['title' => ["query" => $excludeKeyword]]
                        'match_phrase' => ['title' => ["query" => $excludeKeyword, 'slop' => $slop]]
                    ];
                }
                $winBidCondition[] = $winBidTitleNotLike;
            }
        }
        // 用户未指定商机类型，或指定类型中包含中标，则查询条件里带招标带查询条件
        if (empty($dataType) || in_array("中标", $dataType)) {
            $allOpptyCondition["bool"]["should"][] = ["bool" => ["must" => $winBidCondition]];
        }

        // 项目标题的查询
        $projectTitleCondition = [];
        if (!empty($projectKeywords)) {
            $projectTitleCondition = ["bool" => ["should" => []]];
            foreach ($projectKeywords as $keyword) {
                $projectTitleCondition["bool"]["should"][] = [
//                    'match' => ['title' => ["query" => $keyword]]
                    'match_phrase' => ['title' => ["query" => $keyword, 'slop' => $slop]]
                ];
            }
        }

        // 拿地的查询条件
        if ($isLandOpen == 1) {
            $landCondition = [["term" => ["data_type" => "土地"]]];

            if (!empty($landUsageLabels) || !empty($projectKeywords)) {
                $labelCondition = [];
                if (!empty($landUsageLabels)) {
                    $labelCondition = [
                        "nested" => [
                            "path" => "land_usage_label",
                            "query" => ["terms" => [
                                "land_usage_label.name" => $landUsageLabels
                            ]]
                        ]
                    ];
                }

                $landOrCondition = ["bool" => ["should" => []]];
                if (!empty($labelCondition)) {
                    $landOrCondition["bool"]["should"][] = $labelCondition;
                }
                if (!empty($projectTitleCondition)) {
                    $landOrCondition["bool"]["should"][] = $projectTitleCondition;
                }
                $landCondition[] = $landOrCondition;
            }
            // 用户未指定商机类型，或指定类型中包含土地，则查询条件里带招标带查询条件
            if (empty($dataType) || in_array("土地", $dataType)) {
                $allOpptyCondition["bool"]["should"][] = ["bool" => ["must" => $landCondition]];
            }
        }

        // 在建的查询条件
        if ($isBuildingOpen == 1) {
            $buildingCondition = [["term" => ["data_type" => "在建"]]];
            if (!empty($buildingTypes) || !empty($projectKeywords)) {
                $typeCondition = [];
                if (!empty($buildingTypes)) {
                    $typeCondition = ["terms" => ["project_type_label" => $buildingTypes]];
                }

                $buildingOrCondition = ["bool" => ["should" => []]];
                if (!empty($typeCondition)) {
                    $buildingOrCondition["bool"]["should"][] = $typeCondition;
                }
                if (!empty($projectTitleCondition)) {
                    $buildingOrCondition["bool"]["should"][] = $projectTitleCondition;
                }
                $buildingCondition[] = $buildingOrCondition;
            }

            // 用户未指定商机类型，或指定类型中包含在建，则查询条件里带招标带查询条件
            if (empty($dataType) || in_array("在建", $dataType)) {
                $allOpptyCondition["bool"]["should"][] = ["bool" => ["must" => $buildingCondition]];
            }
        }

        // 开盘的查询条件
        if ($isSaleOpen == 1) {
            $saleCondition = [["term" => ["data_type" => "开盘"]]];

            if ((!empty($saleTypes) || !empty($projectKeywords))) {
                $typeCondition = [];
                if (!empty($saleTypes)) {
                    $typeCondition = ["terms" => ["fitment_fee_label" => $saleTypes]];
                }

                $saleOrCondition = ["bool" => ["should" => []]];
                if (!empty($typeCondition)) {
                    $saleOrCondition["bool"]["should"][] = $typeCondition;
                }
                if (!empty($projectTitleCondition)) {
                    $saleOrCondition["bool"]["should"][] = $projectTitleCondition;
                }
                $saleCondition[] = $saleOrCondition;
            }

            // 用户未指定商机类型，或指定类型中包含在建，则查询条件里带招标带查询条件
            if (empty($dataType) || in_array("开盘", $dataType)) {
                $allOpptyCondition["bool"]["should"][] = ["bool" => ["must" => $saleCondition]];
            }
        }

        if (empty($allOpptyCondition)) {
            // 查某个或某几个分类，但是$allOpptyCondition为空，直接返回空数组
            // 例如：datatype为土地，但是土地订阅没打开，就会出现这种情况
            if (!empty($dataType)) {
                return [];
            }
        } else {
            $must[] = $allOpptyCondition;
        }
        return $query;
    }
}
